import 'dart:convert';
import 'dart:io';
import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app_update/azhon_app_update.dart';
import 'package:flutter_app_update/update_model.dart';
import 'package:http/http.dart' as http;
import 'package:macless_haystack/dashboard/dashboard.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:provider/provider.dart';
import 'package:macless_haystack/accessory/accessory_registry.dart';
import 'package:macless_haystack/location/location_model.dart';
import 'package:macless_haystack/preferences/user_preferences_model.dart';
import 'package:macless_haystack/splashscreen.dart';
import 'package:flutter_settings_screens/flutter_settings_screens.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:visibility_detector/visibility_detector.dart';

void main() {
  Settings.init();
  initializeDateFormatting();
  VisibilityDetectorController.instance.updateInterval =
      Duration(milliseconds: 350);
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (ctx) => AccessoryRegistry()),
        ChangeNotifierProvider(create: (ctx) => UserPreferences()),
        ChangeNotifierProvider(create: (ctx) => LocationModel()),
      ],
      child: MaterialApp(
        title: 'Macless Haystack',
        theme: ThemeData(primarySwatch: Colors.blue, fontFamily: 'NotoSansSC'),
        darkTheme: ThemeData.dark(),
        home: const AppLayout(),
      ),
    );
  }
}

class AppLayout extends StatefulWidget {
  const AppLayout({super.key});

  @override
  State<AppLayout> createState() => _AppLayoutState();
}

class _AppLayoutState extends State<AppLayout> {
  @override
  initState() {
    super.initState();

    var accessoryRegistry =
        Provider.of<AccessoryRegistry>(context, listen: false);
    accessoryRegistry.loadAccessories();
  }

  @override
  void dispose() {
    super.dispose();
  }

  bool _firstBuild = true;
  @override
  void didChangeDependencies() {
    // Precache logo for faster load times (e.g. on the splash screen)
    precacheImage(const AssetImage('assets/OpenHaystackIcon.png'), context);
    super.didChangeDependencies();

    if (_firstBuild && !kIsWeb && Platform.isAndroid) {
      _checkAppUpdate();
      _firstBuild = false;
    }
  }

  void _checkAppUpdate() async {
    String versionUrl = 'https://lovelyelfpop.atomgit.net/macless_haystack_pages/version.json';
    //String versionUrl = 'http://10.0.32.114/macless_haystack_pages/version1.json';
    final response = await http.get(Uri.parse(versionUrl));
    if (response.statusCode == 200) {
      Map<String, dynamic> data = json.decode(utf8.decode(response.bodyBytes));

      String? newBuildNumber = data['build_number'];
      String? newVersion = data['version'];
      String? updateLog = data['updateLog'];
      if (newBuildNumber != null &&
          newBuildNumber != '' &&
          newVersion != null &&
          newVersion != '') {
        int? newBuildNum = int.tryParse(newBuildNumber);

        if (newBuildNum != null) {
          PackageInfo packageInfo = await PackageInfo.fromPlatform();
          String buildNumber = packageInfo.buildNumber;
          int? buildNum = int.tryParse(buildNumber);
          if (buildNum != null) {
            if (newBuildNum > buildNum) {
              String appFileUrl =
                  'https://gitee.com/lovelyelfpop/macless-haystack/releases/download/$newVersion/Macless%20Haystack_$newVersion.apk';
              //String appFileUrl =
              //    'http://10.0.32.114/macless_haystack_pages/Macless%20Haystack_$newVersion.apk';
              int? size = await _getNewAppFileSize(appFileUrl);
              if (size != null && size > 0) {
                _showAskUpdateDialog(appFileUrl, newVersion, size, updateLog);
                /* try {
                  OtaUpdate()
                      .execute(appFileUrl)
                      .listen(
                    (OtaEvent event) {
                      setState(() => currentEvent = event);
                    },
                  );
                } catch (e) {
                  print('Failed to make OTA update. Details: $e');
                } */
              }
            }
          }
        }
      }
    }
  }

  Future<int?> _getNewAppFileSize(String appFileUrl) async {
    HttpClient httpClient = HttpClient();
    int? fileSize;

    try {
      HttpClientRequest request =
          await httpClient.headUrl(Uri.parse(appFileUrl));
      HttpClientResponse response = await request.close();

      if (response.statusCode == HttpStatus.ok) {
        fileSize = response.contentLength;
      }
    } catch (e) {
      //print('Exception occurred: $e');
    } finally {
      httpClient.close();
    }

    return fileSize;
  }

  _showAskUpdateDialog(String appFileUrl, String version, int fileSize, String? updateLog) {
    showDialog(
      context: context,
      barrierDismissible: true,
      builder: (BuildContext context) {
        return WillPopScope(
          onWillPop: () => Future.value(true),
          child: AlertDialog(
            title: Text('发现新版本$version'),
            content: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                Text('${(updateLog != null && updateLog != '') ? '更新日志：\n$updateLog' : ''}\n文件大小：${formatBytes(fileSize)}'),
                const SizedBox(height: 16),
                TextButton(
                  onPressed: () {
                    Navigator.pop(context); // 关闭对话框
                    launchUrl(Uri.parse(appFileUrl));
                  },
                  child: const Text('用浏览器下载安装包'),
                ),
              ],
            ),
            // content: Text('新版本号：$version\n文件大小：${formatBytes(fileSize)}'),
            actions: <Widget>[
              TextButton(
                child: Text('取消'),
                onPressed: () => Navigator.of(context).pop(),
              ),
              TextButton(
                child: Text('升级'),
                onPressed: () {
                  UpdateModel model = UpdateModel(
                    appFileUrl,
                    "file.apk",
                    "ic_launcher",
                    '',
                  );
                  AzhonAppUpdate.update(model);
                  Navigator.of(context).pop();
                },
              ),
            ],
          ),
        );
      },
    );
  }

  String formatBytes(int bytes, {int decimals = 2}) {
    if (bytes <= 0) return "0 B";
    const suffixes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
    var i = (log(bytes) / log(1024)).floor();
    return '${(bytes / pow(1024, i)).toStringAsFixed(decimals)} ${suffixes[i]}';
  }

  @override
  Widget build(BuildContext context) {
    bool isInitialized = context.watch<UserPreferences>().initialized;
    bool isLoading = context.watch<AccessoryRegistry>().loading;
    if (!isInitialized || isLoading) {
      return const Splashscreen();
    }

    return const Dashboard();
  }
}
